#include "sessionfriendarea.h"

#include <QScrollArea>
#include <QScrollBar>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QStyleOption>
#include <QPainter>

#include "debug.h"
#include "model/data.h"

/**********************************
 * 整个滚动区域的实现
 *********************************/

sessionFriendArea::sessionFriendArea(QWidget *parent)
    : QScrollArea{parent}
{
    // 1. 设置必要的属性
    // 设置了这个属性, 才能够开启滚动效果
    this->setWidgetResizable(true);
    // 设置滚动条相关的样式
    QString style = "QScrollBar:vertical {border: none;background: rgb(231,231,231);width: 10px;margin: 0px 0px 0px 0px;}\
                     QScrollBar::handle:vertical {background: #c1c1c1;min-height: 20px;border-radius: 5px;}\
                     QScrollBar::handle:vertical:hover {background: #a8a8a8;}\
                     QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {height: 0px;}\
                     QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: none;}";
    // this->verticalScrollBar()->setStyleSheet("QScrollBar:vertical { width: 2px; background-color: rgb(46, 46, 46);}");
    this->verticalScrollBar()->setStyleSheet(style);
    this->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal { height: 0px; }");
    this->setStyleSheet("QWidget { border: none;}");

    // 2. 把 widget 创建出来
    container = new QWidget();
    container->setFixedWidth(300);
    this->setWidget(container);     //得添加到滚动区才知道要滚动哪个

    // 3. 给这个 widget 指定布局管理器, 以便后续添加元素进去
    QVBoxLayout* layout = new QVBoxLayout();
    layout->setSpacing(0);
    layout->setContentsMargins(0,0,0,0);
    layout->setAlignment(Qt::AlignTop);
    container->setLayout(layout);

    // 简单测试一下滚动的效果, 先去掉, 后续添加 Item
    // for(int i = 0;i < 100;++i)
    // {
    //     QPushButton* btn = new QPushButton();
    //     btn->setText("button");
    //     QString style = "QPushButton {background-color: #4CAF50;border: none;color: white;padding: 10px 24px;text-align: \
    //     center;text-decoration: none;display: inline-block;font-size: 16px;\
    //     margin: 4px 2px;border-radius: 8px;}QPushButton:hover {background-color: #45a049;box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);}\
    //         QPushButton:pressed {background-color: #3e8e41;box-shadow: 0 2px 4px 0 rgba(0,0,0,0.2);}";
    //     btn->setStyleSheet(style);
    //     layout->addWidget(btn);
    // }

// 测试
#ifdef TEST_UI
    QIcon icon(":/resource/image/defaultAvatar.png");
    for(int i = 0;i < 10;++i)
    {
        this->addItem(SessionItemType,QString("1"),icon,"小短腿","hhhhhhhhh");
    }
    for(int i = 0;i < 10;++i)
    {
        this->addItem(ApplyItemType,QString("1"),icon,"小短腿");
    }
#endif
}

void sessionFriendArea::clear()
{
    QLayout* layout= container->layout();
    // 遍历布局管理器中的所有元素, 并依次从布局管理器中删除掉
    // 这里如果是头删的话，和vector一样元素会前移，而且count也会一直变化，所以进行尾删
    for(int i = layout->count() - 1;i >= 0;--i)
    {
        // takeAt 就能移除对应下标的元素
        QLayoutItem* item = layout->takeAt(i);
        // 别忘了, 还需要对这个对象进行 "释放"
        if(item->widget())
        {
            // 把这个移除的内容的 widget 进行释放.
            // 正常使用的时候, new 出来的对象添加到布局管理器的....
            delete item->widget();
        }
    }
}

void sessionFriendArea::addItem(ItemType type,const QString& id,const QIcon &avatar, const QString &name, const QString &text)
{
    sessionFriendItem* item = nullptr;
    if(type == SessionItemType)
    {
        item = new sessionItem(this,id,avatar,name,text);
    }
    else if(type == FriendItemType)
    {
        item = new friendItem(this,id,avatar,name,text);
    }
    else if(type == ApplyItemType)
    {
        item = new applyItem(this,id,avatar,name);
    }
    container->layout()->addWidget(item);
}

/**********************************
 * 滚动区域中的 Item 的实现
 *********************************/

sessionFriendItem::sessionFriendItem(QWidget *owner, const QIcon &avatar, const QString &name, const QString &text)
    :owner(owner)
{
    this->setFixedHeight(60);
    this->setStyleSheet("QWidget { background-color: rgb(231, 231, 231); }");

    // 创建网格布局管理器
    QGridLayout* layout = new QGridLayout();
    layout->setContentsMargins(10,5,0,5);
    layout->setHorizontalSpacing(10);
    layout->setVerticalSpacing(0);
    this->setLayout(layout);

    // 创建头像
    QPushButton* avatarBtn = new QPushButton();
    avatarBtn->setFixedSize(50,50);
    avatarBtn->setIconSize(QSize(50,50));
    avatarBtn->setIcon(avatar);
    avatarBtn->setStyleSheet("QPushButton {border: none;}");
    // 水平伸展，垂直固定
    avatarBtn->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);

    // 创建名字
    QLabel* nameLabel = new QLabel();
    nameLabel->setText(name);
    nameLabel->setFixedHeight(20);
    nameLabel->setStyleSheet("QLabel { font-size: 18px; font-weight: 600; text-align: center; font-family: 宋体;}");
    nameLabel->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);

    // 创建消息预览的 label,text可能是上次聊天消息或者是签名
    messageLabel = new QLabel();
    messageLabel->setText(text);
    messageLabel->setFixedHeight(30);
    messageLabel->setStyleSheet("QLabel { text-align: center; font-family: 宋体; }");
    messageLabel->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);

    // 头像处于 0, 0 位置, 占据 2 行, 占据 2 列
    layout->addWidget(avatarBtn,0,0,2,2);
    // 名字处于 0, 2 位置, 占据 1 行, 占据 1 列
    layout->addWidget(nameLabel,0,2,1,8);
    // 消息预览处于 1, 2 位置, 占据 1 行, 占据 1 列
    layout->addWidget(messageLabel,1,2,1,8);
}

// 添加这个样式才能生效
void sessionFriendItem::paintEvent(QPaintEvent *event)
{
    (void) event;
    QStyleOption opt;
    opt.initFrom(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

void sessionFriendItem::mousePressEvent(QMouseEvent *event)
{
    (void) event;
    select();
    activity();
}

void sessionFriendItem::enterEvent(QEnterEvent *event)
{
    (void) event;
    // 当前这个 item 是选中状态, 则背景色不受到该逻辑影响
    if(this->selected)
    {
        return;
    }
    // 设置一个更深的颜色
    this->setStyleSheet("QWidget { background-color: rgb(215, 215, 215);}");
}

void sessionFriendItem::leaveEvent(QEvent *event)
{
    (void) event;
    // 当前这个 item 是选中状态, 则背景色不受到该逻辑影响
    if(this->selected)
    {
        return;
    }
    // 还原背景色
    this->setStyleSheet("QWidget { background-color: rgb(231, 231, 231);}");
}

void sessionFriendItem::select()
{
    // 鼠标点击时会触发这个函数,修改背景颜色，同时也要把之前选中的背景颜色还原
    // 拿到所有的兄弟元素
    // 还原部分
    const QObjectList children = this->parentWidget()->children();
    for(QObject* child : children)
    {
        // 判定是否是 widget.
        if(!child->isWidgetType())
        {
            continue;
        }
        // 确实是 widget, 就把这里的child 强转成 SessionFriendItem
        sessionFriendItem* item = dynamic_cast<sessionFriendItem*>(child);
        if(item->selected)
        {
            item->selected = false;
            item->setStyleSheet("QWidget { background-color: rgb(231, 231, 231); }");
        }
    }

    // 选中修改部分
    this->setStyleSheet("QWidget { background-color: rgb(210, 210, 210); }");
    this->selected = true;
}

void sessionFriendItem::activity(){}

/**********************************
 * 会话item
 *********************************/
sessionItem::sessionItem(QWidget *owner, const QString &chatSessionId, const QIcon &avatar, const QString &name, const QString &lastmsg)
    :sessionFriendItem(owner,avatar,name,lastmsg),
     sessionId(chatSessionId),
     text(lastmsg)
{

}

void sessionItem::activity()
{
    LOG_DEBUG << "session activity" << "\n";
}

/**********************************
 * 好友item
 *********************************/
friendItem::friendItem(QWidget *owner, const QString &friendId, const QIcon &avatar, const QString &name, const QString &desc)
    :sessionFriendItem(owner,avatar,name,desc),
     friendId(friendId),
     description(desc)
{

}

void friendItem::activity()
{
    LOG_DEBUG << "friend activity" << "\n";
}

/**********************************
 * 好友申请item
 *********************************/
applyItem::applyItem(QWidget *owner, const QString &applyId, const QIcon &avatar, const QString &name)
    :sessionFriendItem(owner,avatar,name),
     applyId(applyId)
{
    // 1. 移除父类的 messageLabel
    QGridLayout* glayout = dynamic_cast<QGridLayout*>(this->layout());
    glayout->removeWidget(messageLabel);
    // 要记得释放内存, 否则会内存泄露.
    delete messageLabel;

    // 2. 创建两个按钮出来
    acceptBtn = new QPushButton();
    rejectBtn = new QPushButton();
    acceptBtn->setObjectName("acceptBtn");
    rejectBtn->setObjectName("rejectBtn");
    QString style = "QPushButton#acceptBtn { background-color: #4CAF50; color: white; border: none; padding: 8px 16px;border-radius: 4px;font-weight: bold; }\
                     QPushButton#acceptBtn:hover { background-color: #45a049; }\
                     QPushButton#acceptBtn:pressed { background-color: #3d8b40;}";
    acceptBtn->setText("同意");
    acceptBtn->setStyleSheet(style);

    style = "QPushButton#rejectBtn {background-color: #cccccc;color: #333333;border: none;padding: 8px 16px;border-radius: 4px;font-weight: bold;}\
             QPushButton#rejectBtn:hover {background-color: #ff4444;color: white; }\
             QPushButton#rejectBtn:pressed {background-color: #cc0000;}";
    rejectBtn->setText("拒绝");
    rejectBtn->setStyleSheet(style);

    // 3. 添加到布局管理器中
    glayout->addWidget(acceptBtn,1,2,1,2);
    glayout->addWidget(rejectBtn,1,7,1,2);

}

void applyItem::activity()
{
    LOG_DEBUG << "apply activity" << "\n";
}
